import axios from 'axios';
import store from '../store';
import { storageLoginStatus, getAdToken } from './index';
import Vue from 'vue';

const isDev = process.env.NODE_ENV;

let ajaxCounter = 0;

function rqs(data) {
  return Object.prototype.toString.call(data) === '[object FormData]'
    ? data
    : JSON.stringify(data);
}

/**
 * 处理生产环境和开发环境接口请求地址
 * @param config
 * @returns {any}
 */
function handlePreUrl(config = {}) {
  const { url = '' } = config;
  let fixUrl = `${API_URL_PREFIX}${url}`;
  return Object.assign(config, {
    url: fixUrl
  });
}

const ajax = axios.create({
  baseUrl: '',
  timeout: 60000,
  transformRequest: [rqs],
  headers: {
    'Content-Type': 'application/json'
  }
});

ajax.interceptors.request.use(
  config => {
    config.headers['X-base-token'] = store.state.app.token;
    config.headers['X-channel'] = store.state.app.baseAppId;
    config.headers['X-Request-With'] = 'microb';

    if (config['ad']) {
      config.headers['adToken'] = store.state.app.adToken;
    }

    if (config['loading']) {
      ajaxCounter++;
      window.postMessageToBaseApp({
        theme: 'loading',
        param: true
      });
    }
    // 允许get请求下，可设置请求头
    if (config.method === 'get') {
      config.params = config.data;
    }
    return handlePreUrl(config);
  },
  err => {
    ajaxCounter = 0;
    window.postMessageToBaseApp({
      theme: 'loading',
      param: false
    });
    Vue.prototype.$message.error('网络请求超时');
    return new window.Promise((resolve, reject) => reject(err));
  }
);

ajax.interceptors.response.use(
  response => {
    return new window.Promise((resolve, reject) => {
      if (response.config['loading'] && ajaxCounter > 0) {
        ajaxCounter--;
      }
      if (ajaxCounter <= 0) {
        ajaxCounter = 0;
        window.postMessageToBaseApp({
          theme: 'loading',
          param: false
        });
      }
      // 重映射返回信息
      if (response.data.errorMsg) {
        response.data.errorMessage = response.data.errorMsg;
      }
      let result = response.data;
      // 获取登录标识
      const sessionLoginStatus = storageLoginStatus('', 'get');
      // token失效处理
      if (result.resultCode === 401) {
        window.postMessageToBaseApp({
          theme: 'loginTimeOut',
          param: true
        });
        resolve(result);
      }
      // 处理服务器返回错误
      if (result.errorCode && result.errorCode !== '000000') {
        // 'MC99997'为后台判断为重发请求返回的错误码，如果接口设置了防重，且后台判断为非重发请求，则重新获取新的防重因子adToken
        if (result.errorCode && result.errorCode !== 'MC99997') {
          getAdToken();
        }
        if (!response.config.noShowErrorMsg) {
          result.errorMessage = !result.errorMessage
            ? '服务繁忙'
            : result.errorMessage;
          Vue.prototype.$message.error(result.errorMessage);
        }
      } else if (!sessionLoginStatus && result.errorCode === '000000') {
        storageLoginStatus('1');
      }

      if (response.config.responseType === 'blob') {
        if (
          response.data &&
          response.data.type.indexOf('application/json') > -1
        ) {
          const reader = new FileReader();
          reader.onload = () => {
            if (reader.result) {
              const readerResult = JSON.parse(reader.result);
              Vue.prototype.$message.error(readerResult.errorMessage);
            }
            reject(reader.result);
          };
          reader.readAsText(response.data, 'utf-8');
        } else {
          result = {
            headers: response.headers,
            data: response.data
          };
          resolve(result);
        }
      } else {
        resolve(result);
      }
    });
  },
  err => {
    if (err.response) {
      switch (err.response.status) {
        // 处理token失效逻辑
        case 401:
          window.postMessageToBaseApp({
            theme: 'loginTimeOut',
            param: true
          });
          break;
        case 500:
          Vue.prototype.$message.error('网络异常，请稍后再试！');
          // 如果为防重发接口，重新请求防重因子
          if (err.response.config['ad']) {
            getAdToken();
          }
          break;
        default:
          break;
      }
    }
    ajaxCounter = 0;
    window.postMessageToBaseApp({
      theme: 'loading',
      param: false
    });

    return new window.Promise((resolve, reject) => reject(err));
  }
);

export default ajax;
